/**
 * ReplyGenerator - 回复生成器
 * 
 * 根据聊天上下文和用户目标生成高情商回复
 * Requirements: 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4
 */

import type {
  ParsedChat,
  ReplyOptions,
  ReplyGoal,
  ReplyStyle,
  GeneratedReply,
  EmotionalTone,
  ApiChatMessage,
} from '../types';
import { GitCodeApiService, defaultApiService } from './GitCodeApiService';

/**
 * 长文本阈值（超过此长度需要提供精简版本）
 * Requirements: 2.4
 */
const LONG_TEXT_THRESHOLD = 200;

/**
 * 最小回复数量
 * Requirements: 1.2
 */
const MIN_REPLY_COUNT = 3;

/**
 * 回复目标的中文描述映射
 */
const GOAL_DESCRIPTIONS: Record<ReplyGoal, string> = {
  comfort: '安慰对方，表达理解和支持',
  decline: '委婉拒绝，保持礼貌和尊重',
  thank: '表达感谢，真诚而不过度',
  apologize: '真诚道歉，承担责任',
  congratulate: '祝贺对方，分享喜悦',
  custom: '根据用户自定义目标生成',
};

/**
 * 风格描述映射
 */
const STYLE_DESCRIPTIONS: Record<ReplyStyle, string> = {
  formal: '正式、礼貌、专业的语气',
  casual: '轻松、亲切、日常的语气',
};

/**
 * 生成唯一 ID
 */
function generateId(): string {
  return `reply_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
}

/**
 * 回复生成器类
 */
export class ReplyGenerator {
  private apiService: GitCodeApiService;

  constructor(apiService: GitCodeApiService = defaultApiService) {
    this.apiService = apiService;
  }

  /**
   * 根据聊天上下文生成回复
   * Requirements: 1.1, 1.2, 1.3, 1.4
   * 
   * @param context - 解析后的聊天上下文
   * @param options - 回复选项
   * @returns 生成的回复列表（至少3条）
   */
  async generate(context: ParsedChat, options: ReplyOptions): Promise<GeneratedReply[]> {
    const prompt = this.buildContextPrompt(context, options);
    const messages: ApiChatMessage[] = [
      {
        role: 'system',
        content: this.getSystemPrompt(),
      },
      {
        role: 'user',
        content: prompt,
      },
    ];

    try {
      const response = await this.apiService.chat(messages);
      const replies = this.parseReplies(response, options.style, context.emotionalTone);
      
      // 确保至少返回 MIN_REPLY_COUNT 条回复
      return this.ensureMinReplies(replies, options.style, context.emotionalTone);
    } catch (error) {
      // 如果 API 调用失败，返回默认回复
      console.error('回复生成失败:', error);
      return this.getDefaultReplies(options.style, context.emotionalTone);
    }
  }

  /**
   * 根据目标描述生成回复
   * Requirements: 2.1, 2.2, 2.3, 2.4
   * 
   * @param goal - 目标描述文本
   * @param options - 回复选项
   * @returns 生成的回复列表（只生成用户选择的风格）
   */
  async generateFromGoal(goal: string, options: ReplyOptions): Promise<GeneratedReply[]> {
    const prompt = this.buildGoalPrompt(goal, options);
    const messages: ApiChatMessage[] = [
      {
        role: 'system',
        content: this.getSystemPrompt(),
      },
      {
        role: 'user',
        content: prompt,
      },
    ];

    try {
      const response = await this.apiService.chat(messages);
      const replies = this.parseReplies(response, options.style, 'neutral');
      
      // 确保至少返回 MIN_REPLY_COUNT 条回复
      return this.ensureMinReplies(replies, options.style, 'neutral');
    } catch (error) {
      console.error('回复生成失败:', error);
      return this.getDefaultReplies(options.style, 'neutral');
    }
  }


  /**
   * 获取系统提示词
   */
  private getSystemPrompt(): string {
    return `你是一个高情商的聊天助手，专门帮助用户生成得体、恰当的回复。
你的回复应该：
1. 符合对话的情感基调和社交礼仪
2. 自然流畅，像真人说话
3. 根据指定的风格（正式/非正式）调整语气
4. 避免过于生硬或机械的表达

请按照以下格式输出回复，每条回复用 "---" 分隔：
回复1: [回复内容]
---
回复2: [回复内容]
---
回复3: [回复内容]`;
  }

  /**
   * 构建基于上下文的提示词
   */
  private buildContextPrompt(context: ParsedChat, options: ReplyOptions): string {
    const chatHistory = context.messages
      .map(msg => `${msg.sender}: ${msg.content}`)
      .join('\n');

    const goalDesc = options.goal 
      ? GOAL_DESCRIPTIONS[options.goal] 
      : '根据上下文生成合适的回复';

    const styleDesc = STYLE_DESCRIPTIONS[options.style];

    return `请根据以下聊天记录生成3条高情商回复：

【聊天记录】
${chatHistory}

【情感基调】${context.emotionalTone}
【回复目标】${goalDesc}
【回复风格】${styleDesc}
${options.maxLength ? `【长度限制】不超过 ${options.maxLength} 字` : ''}

请生成3条不同的回复供用户选择。`;
  }

  /**
   * 构建基于目标的提示词
   */
  private buildGoalPrompt(goal: string, options: ReplyOptions): string {
    const styleDesc = STYLE_DESCRIPTIONS[options.style];

    return `请根据以下目标生成3条回复：

【目标描述】${goal}
【回复风格】${styleDesc}
${options.maxLength ? `【长度限制】不超过 ${options.maxLength} 字` : ''}

请生成3条不同的回复供用户选择。`;
  }

  /**
   * 解析 API 返回的回复文本
   */
  private parseReplies(
    response: string,
    style: ReplyStyle,
    emotionalTone: EmotionalTone
  ): GeneratedReply[] {
    const replies: GeneratedReply[] = [];
    
    // 尝试按 "---" 分隔
    const parts = response.split('---').map(p => p.trim()).filter(p => p.length > 0);
    
    for (const part of parts) {
      // 提取回复内容（去除 "回复N:" 前缀）
      const content = part.replace(/^回复\d+[：:]\s*/i, '').trim();
      
      if (content.length > 0) {
        const reply = this.createReply(content, style, emotionalTone);
        replies.push(reply);
      }
    }

    // 如果分隔失败，尝试按行解析
    if (replies.length === 0) {
      const lines = response.split('\n').filter(l => l.trim().length > 0);
      for (const line of lines) {
        const content = line.replace(/^回复\d+[：:]\s*/i, '').replace(/^\d+[.、]\s*/, '').trim();
        if (content.length > 0 && content.length < 500) {
          const reply = this.createReply(content, style, emotionalTone);
          replies.push(reply);
        }
      }
    }

    return replies;
  }

  /**
   * 创建回复对象
   * Requirements: 2.4 - 长文本需要提供精简版本
   */
  private createReply(
    content: string,
    style: ReplyStyle,
    emotionalTone: EmotionalTone
  ): GeneratedReply {
    const reply: GeneratedReply = {
      id: generateId(),
      content,
      style,
      emotionalTone,
    };

    // 如果内容超过阈值，生成精简版本
    if (content.length > LONG_TEXT_THRESHOLD) {
      reply.shortVersion = this.createShortVersion(content);
    }

    return reply;
  }

  /**
   * 创建精简版本
   * Requirements: 2.4
   */
  private createShortVersion(content: string): string {
    // 简单的精简策略：
    // 1. 如果有句号分隔，取前两句
    // 2. 否则截取前 100 字符并添加省略号
    
    const sentences = content.split(/[。！？.!?]/).filter(s => s.trim().length > 0);
    
    if (sentences.length >= 2) {
      const shortContent = sentences.slice(0, 2).join('。') + '。';
      if (shortContent.length <= LONG_TEXT_THRESHOLD) {
        return shortContent;
      }
    }

    // 截取并添加省略号
    const maxLength = Math.min(100, LONG_TEXT_THRESHOLD - 3);
    return content.substring(0, maxLength) + '...';
  }

  /**
   * 确保返回至少 MIN_REPLY_COUNT 条回复
   * Requirements: 1.2
   */
  private ensureMinReplies(
    replies: GeneratedReply[],
    style: ReplyStyle,
    emotionalTone: EmotionalTone
  ): GeneratedReply[] {
    while (replies.length < MIN_REPLY_COUNT) {
      const defaultReplies = this.getDefaultReplies(style, emotionalTone);
      const needed = MIN_REPLY_COUNT - replies.length;
      replies.push(...defaultReplies.slice(0, needed));
    }
    return replies;
  }

  /**
   * 获取默认回复（当 API 调用失败时使用）
   */
  private getDefaultReplies(style: ReplyStyle, emotionalTone: EmotionalTone): GeneratedReply[] {
    const defaultContents: Record<ReplyStyle, Record<EmotionalTone, string[]>> = {
      formal: {
        happy: ['非常感谢您的分享，这真是个好消息！', '很高兴听到这个消息，祝一切顺利！', '这真是太棒了，恭喜您！'],
        sad: ['我理解您的感受，如有需要请随时告诉我。', '请不要太担心，事情会好起来的。', '我在这里支持您，有什么我能帮忙的吗？'],
        comfort: ['请放心，一切都会好起来的。', '我理解您的处境，请保重。', '如果需要帮助，请随时联系我。'],
        funny: ['哈哈，您真幽默！', '这个确实很有趣！', '您的幽默感真好！'],
        grateful: ['不客气，这是我应该做的。', '很高兴能够帮到您。', '您太客气了，随时为您效劳。'],
        apologetic: ['没关系，我理解。', '请不要放在心上。', '这不是什么大问题，别担心。'],
        neutral: ['好的，我明白了。', '收到，感谢您的信息。', '了解，如有其他问题请告诉我。'],
      },
      casual: {
        happy: ['太棒了！真为你高兴！', '哇，这也太好了吧！', '恭喜恭喜！'],
        sad: ['别难过啦，有我在呢。', '抱抱，会好起来的！', '我懂你的感受，加油！'],
        comfort: ['没事的，别想太多。', '放轻松，一切都会过去的。', '我陪你，有什么需要说一声。'],
        funny: ['哈哈哈笑死我了！', '你也太搞笑了吧！', '绝了绝了！'],
        grateful: ['不用谢啦，小事一桩！', '客气啥，咱们谁跟谁！', '能帮到你就好！'],
        apologetic: ['没事没事，别放心上！', '都是小事，不用道歉！', '没关系的，我不介意！'],
        neutral: ['好嘞，知道了！', '收到收到！', 'OK，没问题！'],
      },
    };

    const contents = defaultContents[style][emotionalTone] || defaultContents[style].neutral;
    
    return contents.map(content => this.createReply(content, style, emotionalTone));
  }
}

// 导出单例实例
export const replyGenerator = new ReplyGenerator();
